package com.znyj.servlet.mainController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.znyj.servlet.aes.AesException;
import com.znyj.servlet.aes.MsgCryptTool;
import com.znyj.servlet.constant.SysConstant;
import com.znyj.servlet.entity.MerchantEntity;
import com.znyj.servlet.entity.ReportEntity;
import com.znyj.servlet.entity.ScheduledEntity;
import com.znyj.servlet.entity.TaskEntity;
import com.znyj.servlet.service.MerchantService;
import com.znyj.servlet.service.ReportService;
import com.znyj.servlet.service.ScheduledService;
import com.znyj.servlet.service.TaskService;
import com.znyj.servlet.task.LockTaskMapping;
import com.znyj.servlet.task.ScheduledTaskMapping;
import com.znyj.servlet.task.model.ScheduledTaskModel;
import com.znyj.servlet.thrift.ThriftClient;
import com.znyj.servlet.utilsTool.CommonTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;


/**
 * Created by gaoliwei02 on 17/8/14.
 */
@Controller
@RequestMapping(value = "/crypt")
public class CryptController {
    private static final Logger logger = LoggerFactory.getLogger(CryptController.class);

    @Resource
    private ReportService reportService;

    @Resource
    private MerchantService merchantService;

    @Resource
    private TaskService taskService;

    @Resource
    private MsgCryptTool msgCryptTool;

    @Resource
    private LockTaskMapping lockTaskMapping;

    @Resource
    private ScheduledService scheduledService;

    @Resource
    private ScheduledTaskMapping scheduledTaskMapping;

    @RequestMapping(value = "/getDeviceInfo", method = RequestMethod.POST, produces = "multipart/form-data;charset=utf-8")
    protected
    @ResponseBody
    String getDeviceInfo(@RequestBody String receiveData) throws AesException {
        JSONObject getJson = JSON.parseObject(msgCryptTool.decryptApi(receiveData));
        JSONObject returnMsg = new JSONObject(true);
        String userId = getJson.getString("userId");
        String deviceId = getJson.getString("deviceId");
        String userLocation = getJson.getString("userLocation");
        long timestamp = getJson.getLong("timestamp");

        ReportEntity reportEntity = reportService.findByDeviceId(deviceId);
        //没有这个设备号
        if (reportEntity == null) {
            returnMsg.put("deviceId", deviceId);
            returnMsg.put("onlineStatus", "");
            returnMsg.put("statusA", 0);
            returnMsg.put("statusB", 0);
            returnMsg.put("orderCreateTimeA", 0);
            returnMsg.put("orderCreateTimeB", 0);
            returnMsg.put("orderDurationSecA", 0);
            returnMsg.put("orderDurationSecB", 0);
            returnMsg.put("sigQuality", 0);
            returnMsg.put("batteryLeftTime", 0);//分钟
            returnMsg.put("errorInfo", "device not found");
            returnMsg.put("userIdA", "");
            returnMsg.put("orderIdA", 0);
            returnMsg.put("userIdB", "");
            returnMsg.put("orderIdB", 0);

            returnMsg.put("merchantName", "");
            returnMsg.put("merchantAddress", "");
            returnMsg.put("poiid", "");
            return msgCryptTool.encryptApi(returnMsg.toString());
        } else {
            returnMsg.put("deviceId", reportEntity.getDeviceId());
            returnMsg.put("onlineStatus", reportEntity.getOnlineStatus());
            returnMsg.put("statusA", reportEntity.getStatusA());
            returnMsg.put("statusB", reportEntity.getStatusB());
            returnMsg.put("orderCreateTimeA", reportEntity.getOrderCreateTimeA());
            returnMsg.put("orderCreateTimeB", reportEntity.getOrderCreateTimeB());
            returnMsg.put("orderDurationSecA", reportEntity.getOrderDurationSecA());
            returnMsg.put("orderDurationSecB", reportEntity.getOrderDurationSecB());
            returnMsg.put("sigQuality", reportEntity.getSigQuality());
            returnMsg.put("batteryLeftTime", 99999);
            returnMsg.put("errorInfo", reportEntity.getErrorInfo());
            returnMsg.put("userIdA", reportEntity.getUserIdA());
            returnMsg.put("orderIdA", reportEntity.getOrderIdA());
            //要求改为0，""
//            returnMsg.put("orderIdB", reportEntity.getOrderIdB());
//            returnMsg.put("userIdB", reportEntity.getUserIdB());//0
            returnMsg.put("orderIdB", 0);
            returnMsg.put("userIdB", "");//0
        }
        List<MerchantEntity> entityList = merchantService.findBindMerchant(reportEntity.getDeviceId());

        /*
        if (entityList.size() == 1) {
            CdbMerchantEntity cdbMerchantEntity = entityList.get(0);
            returnMsg.put("merchantName", cdbMerchantEntity.getMerchantName());
            returnMsg.put("merchantAddress", cdbMerchantEntity.getMerchantAddress());
            returnMsg.put("poiid", cdbMerchantEntity.getPoiid());
        } else if (entityList.size() > 1) {
            returnMsg.put("merchantName", "");
            returnMsg.put("merchantAddress", "");
            returnMsg.put("poiid", -1);
        }
        //没有绑定
        else {
            returnMsg.put("merchantName", "");
            returnMsg.put("merchantAddress", "");
            returnMsg.put("poiid", 0);
        }
*/
//        String merchantName = "Aruba Carribean";
//        String merchantAddress = "Pasaraya Grande Lantai G & UG, Jl. Iskandarsyah Raya, RT.3/RW.1, Melawai, Kby. Baru, Kota Jakarta Selatan, Daerah Khusus Ibukota Jakarta, Indonesia - 12160";
//        String poiidTest = "1641e1d6-6d15-4893-abfa-64c890bb2e26";

        String merchantName = "PT Aplikasi Karya Anak Bangsa";
        String merchantAddress = "Pasaraya Blok M, Building B, 6th & 7th Floor, Jl.Iskandarsyah ll No.2, Jakarta Selatan 12160 Indonesia";
        String poiidTest = "1641e1d6-6d15-4893-abfa-64c890bb2e26";




        returnMsg.put("merchantName", merchantName);
        returnMsg.put("merchantAddress", merchantAddress);
        returnMsg.put("poiid", poiidTest);
        logger.info(returnMsg.toString());
        return msgCryptTool.encryptApi(returnMsg.toString());
    }

    //进来时只是open命令
    //api发送进来的还是原来的userId 通过获取deviceInfo获取已经使用的时间 然后减去剩下的duration时间

    @RequestMapping(value = "/openDevice", method = RequestMethod.POST, produces = "multipart/form-data;charset=utf-8")
    protected
    @ResponseBody
    String openDevice(@RequestBody String receiveData) throws InterruptedException, AesException {
        JSONObject getJson = JSON.parseObject(msgCryptTool.decryptApi(receiveData));

        JSONObject returnMsg = new JSONObject(true);
        String userId = getJson.getString("userId");
        String deviceId = getJson.getString("deviceId");
        long createTime = getJson.getLong("createTime");
        long durationSec = getJson.getLong("durationSec");
        String userLocation = getJson.getString("userLocation");
        int port = getJson.getInteger("port");
        int actionMsg = getJson.getInteger("actionMsg");
        String controlMsg = getJson.getString("controlMsg");

        if (lockTaskMapping.isContainDevice(deviceId)) {
            Date date = new Date(createTime);
            logger.info("deviceLock :{}" + date.toString());
            returnMsg.put("deviceId", deviceId);
            returnMsg.put("userId", userId);
            returnMsg.put("orderId", -1);
            returnMsg.put("status", SysConstant.API_ERROR_CODE.API_DEVICE_LOCK);//port or action error
        }

        if (createTime < 1506787200) {
            Date date = new Date(createTime);
            logger.info("timestamp is invalid:{}" + date.toString());
            returnMsg.put("deviceId", deviceId);
            returnMsg.put("userId", userId);
            returnMsg.put("orderId", -1);
            returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TIMESTAMP_INVALID);//port or action error
        }

        //PORT或者ACTION必须正确 port0a，1b，2all action0open 1close
        String finalCtrlMsg = CommonTool.parseCtrlMsg(2, actionMsg, controlMsg);
        logger.info("thrift api{}" + finalCtrlMsg + " port{}" + port);
        if (finalCtrlMsg.equals("error")) {
            returnMsg.put("deviceId", deviceId);
            returnMsg.put("userId", userId);
            returnMsg.put("orderId", -1);
            returnMsg.put("status", SysConstant.API_ERROR_CODE.API_PORT_ACTION_ERR);//port or action error
        }

        //开始发送命令
        else {
            JSONObject putJson = ThriftClient.taskSendThriftApi(userId, deviceId, createTime, durationSec, finalCtrlMsg, userLocation);
            //如果thrift不是发送成功，有错误立即回复错误
            //returnMsg.put("deviceId", putJson.getString("deviceId"));
            //returnMsg.put("userId", putJson.getString("userId"));
            //要求修改
            returnMsg.put("deviceId", deviceId);
            returnMsg.put("userId", userId);
            returnMsg.put("orderId", putJson.getLong("orderId"));
            returnMsg.put("status", putJson.getLong("status"));

            //open
            if (actionMsg == 0) {
                //kafka 发送
                if (putJson.getLong("status") == SysConstant.API_ERROR_CODE.THRIFT_SEND_TASK_OK) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("userId", userId);
                    jsonObject.put("deviceId", deviceId);
                    jsonObject.put("createTime", createTime);
                    jsonObject.put("durationSec", durationSec);
                    jsonObject.put("controlMsg", CommonTool.parseCtrlMsg(2, 1, controlMsg));
                    jsonObject.put("userLocation", userLocation);

                    jsonObject.put("openOrderId", putJson.getLong("orderId"));
                    //KafkaClt kafkaClt = new KafkaClt("101.236.32.51:9092");
                    //kafkaClt.sendMsg("closeTimer", jsonObject.toString());

                    ScheduledEntity scheduledEntity = new ScheduledEntity();
                    scheduledEntity.setUserId(userId);
                    scheduledEntity.setDeviceId(deviceId);
                    scheduledEntity.setCreateTime(new Timestamp(createTime));
                    scheduledEntity.setDurationSec(durationSec);
                    scheduledEntity.setControlMsg(CommonTool.parseCtrlMsg(2, 1, controlMsg));
                    scheduledEntity.setUserLocation(userLocation);

                    scheduledEntity.setOpenOrderId(putJson.getLong("orderId"));
                    scheduledEntity.setExtraDelay(0);
                    scheduledEntity.setExecuteResult("");

                    ScheduledTaskModel scheduledTaskModel = new ScheduledTaskModel(scheduledEntity);
                    scheduledService.insertScheduled(scheduledTaskModel.scheduledEntity);
                    scheduledTaskMapping.add(scheduledTaskModel.scheduledEntity.getOpenOrderId(), scheduledTaskModel);
                    logger.info("post kafka&scheduled:{} " + jsonObject.toString());
                }
            }
        }
        logger.info(returnMsg.toString());
        return msgCryptTool.encryptApi(returnMsg.toString());
    }

    @RequestMapping(value = "/getOrderInfo", method = RequestMethod.POST, produces = "multipart/form-data;charset=utf-8")
    protected
    @ResponseBody
    String getOrderInfo(@RequestBody String receiveData) throws AesException {
        JSONObject getJson = JSON.parseObject(msgCryptTool.decryptApi(receiveData));
        JSONObject returnMsg = new JSONObject(true);
        long orderId = getJson.getLong("orderId");
        TaskEntity taskEntity = taskService.findByOrderId(orderId);

        if (taskEntity == null) {
            returnMsg.put("deviceId", "");
            returnMsg.put("userId", "");
            returnMsg.put("orderId", orderId);
            returnMsg.put("status", SysConstant.API_ERROR_CODE.API_ORRDER_NO_FOUND);
        }

        //还没有收到
        else if (taskEntity.getSendStatus() != SysConstant.API_ERROR_CODE.RECEIVE_PACKAGE_OK) {
            Timestamp timestamp = taskEntity.getCreateTime();
            Timestamp now = new Timestamp(System.currentTimeMillis());
            //超时失败
            if ((now.getTime() - timestamp.getTime()) > SysConstant.TASK_TIMEOUT) {
                returnMsg.put("deviceId", taskEntity.getDeviceId());
                returnMsg.put("userId", taskEntity.getUserId());
                returnMsg.put("orderId", taskEntity.getOrderId());
                returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TASK_TIMEOUT);
            } else {
                returnMsg.put("deviceId", taskEntity.getDeviceId());
                returnMsg.put("userId", taskEntity.getUserId());
                returnMsg.put("orderId", taskEntity.getOrderId());
                returnMsg.put("status", SysConstant.API_ERROR_CODE.API_WAIT_TASK);
            }
        }

        //发送成功，开始查询设备是否接收到
        else if (taskEntity.getSendStatus() == SysConstant.API_ERROR_CODE.RECEIVE_PACKAGE_OK) {
            //如果是A口
            String msg = taskEntity.getControlMsg();

            //A
            if (msg.equals("cdbaopen")) {
                long tempOrderId = reportService.getChannalAOrderId(taskEntity.getDeviceId());
                if (orderId == tempOrderId) {
                    //发送队列！！！！！！！！！！！！！！！！！！！！
                    returnMsg.put("deviceId", taskEntity.getDeviceId());
                    returnMsg.put("userId", taskEntity.getUserId());
                    returnMsg.put("orderId", taskEntity.getOrderId());
                    returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TASK_EXECUTE_SUCCESS);
                    //
                } else {
                    returnMsg.put("deviceId", taskEntity.getDeviceId());
                    returnMsg.put("userId", taskEntity.getUserId());
                    returnMsg.put("orderId", taskEntity.getOrderId());
                    returnMsg.put("status", SysConstant.API_ERROR_CODE.API_ORDERID_NOT_EQ);
                }
            } else if (msg.equals("cdbaclose")) {
                returnMsg.put("deviceId", taskEntity.getDeviceId());
                returnMsg.put("userId", taskEntity.getUserId());
                returnMsg.put("orderId", taskEntity.getOrderId());
                returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TASK_EXECUTE_SUCCESS);

            }
            //B
            else if (msg.equals("cdbbopen")) {
                long tempOrderId = reportService.getChannalBOrderId(taskEntity.getDeviceId());
                if (orderId == tempOrderId) {
                    //发送队列！！！！！！！！！！！！！！！！！！！！
                    returnMsg.put("deviceId", taskEntity.getDeviceId());
                    returnMsg.put("userId", taskEntity.getUserId());
                    returnMsg.put("orderId", taskEntity.getOrderId());
                    returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TASK_EXECUTE_SUCCESS);
                    //
                } else {
                    returnMsg.put("deviceId", taskEntity.getDeviceId());
                    returnMsg.put("userId", taskEntity.getUserId());
                    returnMsg.put("orderId", taskEntity.getOrderId());
                    returnMsg.put("status", SysConstant.API_ERROR_CODE.API_ORDERID_NOT_EQ);
                }
            } else if (msg.equals("cdbbclose")) {
                returnMsg.put("deviceId", taskEntity.getDeviceId());
                returnMsg.put("userId", taskEntity.getUserId());
                returnMsg.put("orderId", taskEntity.getOrderId());
                returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TASK_EXECUTE_SUCCESS);
            }

            //ALL
            else if (msg.equals("cdbopen")) {
                long tempOrderId = reportService.getChannalAOrderId(taskEntity.getDeviceId());
                if (orderId == tempOrderId) {
                    //发送队列！！！！！！！！！！！！！！！！！！！！
                    returnMsg.put("deviceId", taskEntity.getDeviceId());
                    returnMsg.put("userId", taskEntity.getUserId());
                    returnMsg.put("orderId", taskEntity.getOrderId());
                    returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TASK_EXECUTE_SUCCESS);
                    //
                } else {
                    returnMsg.put("deviceId", taskEntity.getDeviceId());
                    returnMsg.put("userId", taskEntity.getUserId());
                    returnMsg.put("orderId", taskEntity.getOrderId());
                    returnMsg.put("status", SysConstant.API_ERROR_CODE.API_ORDERID_NOT_EQ);
                }
            } else if (msg.equals("cdbclose")) {
                returnMsg.put("deviceId", taskEntity.getDeviceId());
                returnMsg.put("userId", taskEntity.getUserId());
                returnMsg.put("orderId", taskEntity.getOrderId());
                returnMsg.put("status", SysConstant.API_ERROR_CODE.API_TASK_EXECUTE_SUCCESS);
            }

            //CTRL
            else {
                returnMsg.put("deviceId", taskEntity.getDeviceId());
                returnMsg.put("userId", taskEntity.getUserId());
                returnMsg.put("orderId", taskEntity.getOrderId());
                returnMsg.put("status", SysConstant.API_ERROR_CODE.API_CTRL);
            }
        }
        return msgCryptTool.encryptApi(returnMsg.toString());
    }

//    /crypt/scheduleTask POST "multipart/form-data;charset=utf-8"
//    {
//        "userId":String
//        "deviceId":String
//        "orderId":long
//        "createTime":long
//        "durationSec":long
//        "userLocation":String
//        "controlMsg":String
//    }
//
//    /crypt/getOrderIdInfo POST "multipart/form-data;charset=utf-8"
//    {
//        "orderId":long
//    }

    @RequestMapping(value = "/scheduleTask", method = RequestMethod.POST, produces = "multipart/form-data;charset=utf-8")
    protected
    @ResponseBody
    String scheduleTask(@RequestBody String receiveData) {
        JSONObject getJson = JSON.parseObject(receiveData);

        JSONObject returnMsg = new JSONObject(true);
        String userId = getJson.getString("userId");
        String deviceId = getJson.getString("deviceId");
        long orderId = getJson.getLong("orderId");
        long createTime = getJson.getLong("createTime");
        long durationSec = getJson.getLong("durationSec");
        String userLocation = getJson.getString("userLocation");
        String controlMsg = getJson.getString("controlMsg");

        //PORT或者ACTION必须正确
        if (!controlMsg.equals("cdbclose")) {
            returnMsg.put("deviceId", deviceId);
            returnMsg.put("userId", userId);
            returnMsg.put("orderId", -1);
            returnMsg.put("status", SysConstant.API_ERROR_CODE.API_PORT_ACTION_ERR);//port or action error
            logger.info("scheduleTask api fail{}" + getJson.toString());
        }
        //开始发送命令
        else {
            JSONObject putJson = ThriftClient.taskSendThriftApi(userId, deviceId, createTime, durationSec, controlMsg, userLocation);
            //如果thrift不是发送成功，有错误立即回复错误
            returnMsg.put("deviceId", putJson.getString("deviceId"));
            returnMsg.put("userId", putJson.getString("userId"));
            returnMsg.put("orderId", putJson.getLong("orderId"));
            returnMsg.put("status", putJson.getLong("status"));
            logger.info("scheduleTask api success{}" + getJson.toString() + " thrift return status{}" + putJson.getLong("status"));
        }
        return returnMsg.toString();
//            THRIFT_SEND_TASK_OK = 1;
//            THRIFT_MSG_INVALID = 2;
//            THRIFT_DEV_OFFLINE = 3;
//            API_PORT_ACTION_ERR = 4;
//            THRIFT_OPEN_ALREADY = 11;
//            THRIFT_CLOSE_ALREADY = 12;
    }

    @RequestMapping(value = "/getOrderIdInfo", method = RequestMethod.POST, produces = "multipart/form-data;charset=utf-8")
    protected
    @ResponseBody
    String getOrderIdInfo(@RequestBody String receiveData) {
        JSONObject getJson = JSON.parseObject(receiveData);
        long orderId = getJson.getLong("orderId");

        TaskEntity taskEntity = taskService.findByOrderId(orderId);
        JSONObject returnMsg = new JSONObject(true);
        if (taskEntity == null) {
            returnMsg.put("userId", taskEntity.getUserId());
            returnMsg.put("deviceId", taskEntity.getDeviceId());
            returnMsg.put("orderId", taskEntity.getOrderId());
            returnMsg.put("createTime", taskEntity.getCreateTime().getTime());
            returnMsg.put("durationSec", taskEntity.getDurationSec());
            returnMsg.put("sendStatus", taskEntity.getSendStatus());
            returnMsg.put("controlMsg", taskEntity.getControlMsg());
            returnMsg.put("userLocation", taskEntity.getUserLocation());
            returnMsg.put("executeResult", taskEntity.getExecuteResult());
            logger.error("getOrderIdInfo api success{}" + returnMsg.toString());
        } else {
            returnMsg.put("userId", "");
            returnMsg.put("deviceId", "");
            returnMsg.put("orderId", orderId);
            returnMsg.put("createTime", 0);
            returnMsg.put("durationSec", 0);
            returnMsg.put("sendStatus", 0);
            returnMsg.put("controlMsg", "");
            returnMsg.put("userLocation", "");
            returnMsg.put("executeResult", "");
            logger.error("getOrderIdInfo api orderId unfound{}" + orderId);
        }
        return returnMsg.toString();
    }
}

